home *** CD-ROM | disk | FTP | other *** search
- Subject: v20i077: A package to remove common lint/malloc complaints
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Bob Lewis <uunet!tessi!bobl>
- Posting-number: Volume 20, Issue 77
- Archive-name: memlintok
-
- [ Various tools and tricks for doing this abound; might as well get one
- in the archives. Please don't submit any others unless they're
- significantly better or different. /r$ ]
-
- "memlintok.h" is a header file that can be used to politely shut lint(1)
- up about casting results of memory allocation functions malloc(3),
- realloc(3), and calloc(3). It also stops complaints about the argument of
- free(3).
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: README Makefile good memlintok.3 memlintok.h t_memlintok.c
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f README -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"README\"
- else
- echo shar: Extracting \"README\" \(1747 characters\)
- sed "s/^X//" >README <<'END_OF_README'
- X"memlintok.h" is a header file that can be used to politely shut lint(1) up
- Xabout casting results of memory allocation functions malloc(3), realloc(3),
- Xand calloc(3). It also stops complaints about the argument of free(3).
- X
- XCONTENTS
- X--------
- XFiles in this distribution are:
- X
- XREADME you're reading it
- XMakefile has several useful targets, including "install" and "test"
- Xgood good results for "make test"
- Xmemlintok.3 man page
- Xmemlintok.h the header file itself
- Xt_memlintok.c a test/demo program
- X
- XDISCUSSION
- X----------
- XOne common way of ignoring lint errors is to do something like:
- X
- X #ifdef lint
- X #define malloc(arg) NULL
- X #endif
- X
- XThe trouble with doing things this way is that lint will not then be able to
- Xcheck malloc's argument, so you could get away with something like:
- X
- X char *p;
- X char *q;
- X ...
- X p = malloc(q);
- X
- XThe macros here are a bit more sophisticated, so that the memory functions
- Xget invoked in a syntactically correct and properly-typed (although
- Xsemantically incorrect) fashion and the arguments get checked
- Xindependently. The man page describes their use.
- X
- XThe file also includes a macro MR_ALLOC_LINTOK that is simply a compact form
- Xof the commonly-occurring code to allocate memory if a (typically static)
- Xpointer is NULL and to reallocate it if the pointer isn't NULL.
- X
- XThere are also macros to do some primitive exception handling of the memory
- Xallocation function. See the man page for more on these.
- X
- XAs I developed it with my own resources, I'm releasing this code to the
- Xpublic domain. I hereby deny any responsibility for its use or any damages
- Xresulting from same.
- X
- XNevertheless, if anyone has any problems with it, questions about it, or
- Ximprovements to it, please let me know.
- X
- X - Bob Lewis
- X bobl@tessi.uucp
- END_OF_README
- if test 1747 -ne `wc -c <README`; then
- echo shar: \"README\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f Makefile -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"Makefile\"
- else
- echo shar: Extracting \"Makefile\" \(951 characters\)
- sed "s/^X//" >Makefile <<'END_OF_Makefile'
- X# $Header: Makefile,v 1.4 89/05/02 15:06:48 bobl Exp $
- X
- Xdefault: new
- X
- X#
- X# This is where you want the header to go. It might be advisable to
- X# put it in some local directory rather than this default one...
- X#
- XHDR_DEST = /usr/include
- X
- X#
- X# The man page goes here. Again, you may have some local place to put it.
- X#
- XMAN_DEST = /usr/man/man3
- X
- XFILES = \
- X README \
- X Makefile \
- X good \
- X memlintok.3 \
- X memlintok.h \
- X t_memlintok.c
- X
- Xclean:
- X rm -f t_memlintok new core a.out *.o memlintok.shar
- X
- Xnew: t_memlintok
- X t_memlintok >new
- X
- Xt_memlintok: t_memlintok.c memlintok.h
- X cc t_memlintok.c -o t_memlintok
- X
- Xtest: new t_memlintok
- X @echo "# comparing new results with known good ones:"
- X diff new good
- X @echo "# should be no lint errors:"
- X lint -bachx t_memlintok.c
- X
- Xupdate: new
- X mv -f new good
- X
- Xshar: memlintok.shar
- X
- Xmemlintok.shar: $(FILES)
- X shar $(FILES) >memlintok.shar
- X
- Xinstall: memlintok.h memlintok.3
- X cp memlintok.h $(HDR_DEST)
- X cp memlintok.3 $(MAN_DEST)
- X
- X
- END_OF_Makefile
- if test 951 -ne `wc -c <Makefile`; then
- echo shar: \"Makefile\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f good -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"good\"
- else
- echo shar: Extracting \"good\" \(244 characters\)
- sed "s/^X//" >good <<'END_OF_good'
- X100 ints malloc'd
- X200 ints realloc'd
- X25 ints mr_alloc'd (realloc'd)
- X500 ints calloc'd
- X1000 ints mr_alloc'd (malloc'd)
- X50 ints calloc'd (or else)
- X100 ints malloc'd (or else)
- X200 ints realloc'd (or else)
- X400 ints mr_alloc'd (realloc'd) (or else)
- END_OF_good
- if test 244 -ne `wc -c <good`; then
- echo shar: \"good\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f memlintok.3 -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"memlintok.3\"
- else
- echo shar: Extracting \"memlintok.3\" \(4706 characters\)
- sed "s/^X//" >memlintok.3 <<'END_OF_memlintok.3'
- X.TH LINTOK 3 "2 May 1989"
- X.SH NAME
- Xmemlintok \- package to stop lint complaints about memory allocation
- X.SH SYNOPSIS
- X.LP
- X#include "memlintok.h"
- X.SH DESCRIPTION
- X.LP
- XThis package contains cpp macro definitions that
- Xstop lint from complaining about the memory management functions
- X.IR malloc (3),
- X.IR calloc (3),
- X.IR realloc (3),
- Xand
- X.IR free (3)
- X(hereafter, we'll call these the "\fI*alloc\fP(3)" functions),
- Xwhile at the same time performing checks of their arguments.
- XThere are two sets of macros defined here: one without exception handling
- X(like the
- X.IR *alloc (3)
- Xfunctions themselves) and one with.
- X.LP
- XThe macros without exception handling are:
- X.IP ""
- XCALLOC_LINTOK(ptr, nelem, type)
- X.br
- XMALLOC_LINTOK(ptr, nelem, type)
- X.br
- XREALLOC_LINTOK(ptr, nelem, type)
- X.br
- XFREE_LINTOK(ptr)
- X.br
- X.LP
- Xwhere "ptr" is a variable of type "type *". After invoking any
- Xof the "*ALLOC_LINTOK" macros, "ptr" will either be NULL (if and
- Xonly if the
- Xunderlying function returned it) or it will point to an array of
- X"nelem" objects of type "type".
- X.LP
- XNote that the usage of MALLOC_LINTOK, CALLOC_LINTOK, and
- XREALLOC_LINTOK requires more than a name change. An original
- Xcall of the form:
- X.IP
- Xptr = (type *) malloc(nelem * sizeof(type))
- X.LP
- Xmust be replaced by
- X.IP
- XMALLOC_LINTOK(ptr, nelem, type)
- X.LP
- Xand similarly for CALLOC_LINTOK and REALLOC_LINTOK. All three
- Xmacros "return" values and may therefore be used as part of
- Xexpressions.
- X.LP
- XIf a macro's result is compared with NULL, lint will usually complain
- Xif NULL is cast to anything. For example, this will produce a lint error:
- X.IP
- Xint *ia;
- X.br
- X ...
- X.br
- Xif (MALLOC_LINTOK(ia, 42, int) == (int *) NULL)
- X.br
- X ...
- X.LP
- XBut since uncast 0 (i.e., NULL) is always a valid pointer, it
- Xis unnecessary to cast it to anything.
- XRemoving the cast stops the lint complaint:
- X.IP
- X ...
- X.br
- Xif (MALLOC_LINTOK(ia, 42, int) == NULL)
- X.br
- X ...
- X.LP
- XIf the macro invocation doesn't appear within an expression,
- Xyou will need to cast the *ALLOC_LINTOK()
- Xinvocations to
- X.B void
- Xif you want to get rid of the
- X"*alloc returns value which is sometimes ignored"
- Xand
- X"*alloc returns value which is always ignored"
- Xmessages.
- X.LP
- XYou can mix invocations of these macros with calls to the original
- Xfunctions. The only difference is in the lint behavior.
- X.LP
- XA common way of invoking the memory management functions is to call
- X.IR malloc ()
- Xif a
- Xpointer is NULL (usually the first time it's set) and
- X.IR realloc ()
- Xif it isn't NULL (usually on subsequent times). The simple macro
- X.IP
- XMR_ALLOC_LINTOK(ptr, nelem, type)
- X.LP
- Xdoes this with MALLOC_LINTOK() and REALLOC_LINTOK().
- X.LP
- XSince memory allocation failure is often an exceptional condition,
- X"memlintok.h" also has definitions of four other useful macros that include
- Xexception handling:
- X.IP
- XCALLOC_OR_ELSE_LINTOK(ptr, nelem, type)
- X.br
- XMALLOC_OR_ELSE_LINTOK(ptr, nelem, type)
- X.br
- XREALLOC_OR_ELSE_LINTOK(ptr, nelem, type)
- X.br
- XMR_ALLOC_OR_ELSE_LINTOK(ptr, nelem, type)
- X.br
- X.LP
- XEach of these macros invokes the corresponding *ALLOC_LINTOK() macro and,
- Xif that macro fails, invokes another macro:
- X.IP
- XERROR_EXIT_LINTOK(nelem, size)
- X.LP
- XWhere "nelem" is the number of elements of "size" bytes attempting to be
- Xallocated.
- X.LP
- XA default ERROR_EXIT_LINTOK(nelem, size), which prints an informative
- Xmessage and dies, is also defined, but you are free to redefine it
- X(after including "memlintok.h" and before invoking any of the macros herein
- X-- remember to "#undef ERROR_EXIT_LINTOK" first)
- Xif you want to do your own error handling.
- X.SH "SEE ALSO"
- X.BR malloc (3),
- X.BR stdio (3S)
- X.SH NOTE
- X.LP
- X"memlintok.h" assumes NULL is defined in <stdio.h> (which is usually the case).
- X.LP
- XIt also assumes the cpp symbol "lint" is defined when and only when the
- Xcode is being passed through lint and not generating real executable code.
- X.LP
- XThese macros have been tested under SunOS, HP-UX, and Apollo DOMAIN/IX.
- X.SH BUGS
- X.LP
- XThese macros are intended for use with the dynamic
- Xallocation of single elements of fixed size (i.e. structs or typedefs)
- Xor variably-sized arrays of same.
- XIn the author's experience, this covers most uses of the
- X.IR \fI*alloc\fP (3)
- Xfunctions.
- XThe macros do not work well, however, when creating variably-sized single
- Xstructures that are not arrays.
- X.LP
- XAt least one version of
- X.IR lint (1)
- X(SunOS 4.0) complains when these macros
- Xare used with "void *" pointers.
- XIt needn't.
- X.LP
- XApollo DOMAIN/IX
- X.IR lint (1)
- Xgenerates several bogus (I believe) complaints about the default exception
- Xhandling macro.
- X.SH AUTHOR
- X.LP
- XBob Lewis (bobl@tessi.uucp) produced these macros using his own
- Xresources and hereby releases them to the public domain.
- XThe author will not be held responsible for their use, misuse,
- Xabuse, or any damages arising from same.
- END_OF_memlintok.3
- if test 4706 -ne `wc -c <memlintok.3`; then
- echo shar: \"memlintok.3\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f memlintok.h -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"memlintok.h\"
- else
- echo shar: Extracting \"memlintok.h\" \(2986 characters\)
- sed "s/^X//" >memlintok.h <<'END_OF_memlintok.h'
- X#ifndef INCLUDED_LINTOK
- X
- X/* $Header: memlintok.h,v 1.3 89/05/02 15:01:43 bobl Locked $ */
- X
- X/*
- X * These definitions stop lint from complaining about malloc, calloc,
- X * realloc, and free while at the same time performing checks of
- X * their arguments. See the memlintok(3) man page for more details.
- X *
- X * Bob Lewis (bobl@tessi.uucp) produced these macros using his own
- X * resources and hereby releases them to the public domain.
- X * The author will not be held responsible for their use, misuse,
- X * abuse, or any damages arising from same.
- X */
- X
- X#ifndef NULL
- X#include <stdio.h>
- X#endif
- X
- Xextern char *calloc();
- X#ifdef lint
- X#define CALLOC_LINTOK(ptr, nelem, type) \
- X calloc((ptr = (type *) NULL, (unsigned) (nelem)), (unsigned) sizeof(type))
- X#else
- X#define CALLOC_LINTOK(ptr, nelem, type) \
- X (ptr = (type *) calloc((unsigned) (nelem), (unsigned) sizeof(type)))
- X#endif
- X
- Xextern char *malloc();
- X#ifdef lint
- X#define MALLOC_LINTOK(ptr, nelem, type) \
- X malloc((ptr = (type *) NULL, (unsigned) ((nelem) * sizeof(type))))
- X#else
- X#define MALLOC_LINTOK(ptr, nelem, type) \
- X (ptr = (type *) malloc((unsigned) ((nelem) * sizeof(type))))
- X#endif
- X
- Xextern char *realloc();
- X#ifdef lint
- X#define REALLOC_LINTOK(ptr, nelem, type) \
- X realloc( \
- X (ptr = (type *) NULL, (char *) NULL), \
- X (unsigned) ((nelem) * sizeof(type)))
- X#else
- X#define REALLOC_LINTOK(ptr, nelem, type) \
- X (ptr = (type *) realloc( \
- X (char *) ptr, \
- X (unsigned) ((nelem) * sizeof(type))))
- X#endif
- X
- X/* common use of malloc/realloc -- use it or don't use it */
- X#define MR_ALLOC_LINTOK(ptr, nelem, type) \
- X ( (ptr) == NULL \
- X ? MALLOC_LINTOK(ptr, (nelem), type) \
- X : REALLOC_LINTOK(ptr, (nelem), type) )
- X
- X/*
- X * These next macros invoke CALLOC_LINTOK, MALLOC_LINTOK, REALLOC_LINTOK,
- X * and MR_ALLOC_LINTOK with an error exit if they fail.
- X *
- X * If you want to handle your own memory allocation errors, just
- X * "#undef ERROR_EXIT_LINTOK" and define your own.
- X */
- X#define ERROR_EXIT_LINTOK(nelem, size) \
- X { \
- X (void) fprintf(stderr, \
- X "Memory allocation of %d * %d bytes on line %d of \"%s\" failed.\n", \
- X (nelem), (size), __LINE__, __FILE__); \
- X exit(1); \
- X }
- X
- X#define CALLOC_OR_ELSE_LINTOK(ptr, nelem, type) \
- X { \
- X if (CALLOC_LINTOK(ptr, (nelem), type) == NULL) \
- X ERROR_EXIT_LINTOK((nelem), sizeof(type)); \
- X }
- X
- X#define MALLOC_OR_ELSE_LINTOK(ptr, nelem, type) \
- X { \
- X if (MALLOC_LINTOK(ptr, (nelem), type) == NULL) \
- X ERROR_EXIT_LINTOK((nelem), sizeof(type)); \
- X }
- X
- X#define REALLOC_OR_ELSE_LINTOK(ptr, nelem, type) \
- X { \
- X if (REALLOC_LINTOK(ptr, (nelem), type) == NULL) \
- X ERROR_EXIT_LINTOK((nelem), sizeof(type)); \
- X }
- X
- X#define MR_ALLOC_OR_ELSE_LINTOK(ptr, nelem, type) \
- X { \
- X if (MR_ALLOC_LINTOK(ptr, (nelem), type) == NULL) \
- X ERROR_EXIT_LINTOK((nelem), sizeof(type)); \
- X }
- X
- Xextern free();
- X#ifdef lint
- X#define FREE_LINTOK(ptr) \
- X free((ptr = NULL, (char *) NULL))
- X#else
- X#define FREE_LINTOK(ptr) \
- X free((char *) ptr)
- X#endif
- X
- X/* We could have a "CFREE_LINTOK", but what's the point? */
- X
- X#define INCLUDED_LINTOK
- X#endif
- X
- END_OF_memlintok.h
- if test 2986 -ne `wc -c <memlintok.h`; then
- echo shar: \"memlintok.h\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f t_memlintok.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"t_memlintok.c\"
- else
- echo shar: Extracting \"t_memlintok.c\" \(1438 characters\)
- sed "s/^X//" >t_memlintok.c <<'END_OF_t_memlintok.c'
- X/* $Header: t_memlintok.c,v 1.3 89/05/02 15:07:08 bobl Exp $ */
- X
- X#include <stdio.h>
- X
- X#include "memlintok.h"
- X
- Xmain()
- X{
- X int *p, *q;
- X
- X if (MALLOC_LINTOK(p, 100, int) == NULL)
- X fail("can't malloc 100 ints\n");
- X else
- X succeed("100 ints malloc'd\n");
- X
- X (void) REALLOC_LINTOK(p, 200, int);
- X if (p == NULL)
- X fail("can't realloc 200 ints\n");
- X else
- X succeed("200 ints realloc'd\n");
- X
- X if (MR_ALLOC_LINTOK(p, 25, int) == NULL)
- X fail("can't mr_alloc (realloc) 25 ints\n");
- X else
- X succeed("25 ints mr_alloc'd (realloc'd)\n");
- X
- X if (CALLOC_LINTOK(q, 500, int) == NULL)
- X fail("can't calloc 500 ints\n");
- X else
- X succeed("500 ints calloc'd\n");
- X q[0] = 0;
- X FREE_LINTOK(q);
- X
- X FREE_LINTOK(p);
- X p = NULL;
- X if (MR_ALLOC_LINTOK(p, 1000, int) == NULL)
- X fail("can't mr_alloc (malloc) 1000 ints\n");
- X else
- X succeed("1000 ints mr_alloc'd (malloc'd)\n");
- X
- X CALLOC_OR_ELSE_LINTOK(p, 50, int);
- X succeed("50 ints calloc'd (or else)\n");
- X MALLOC_OR_ELSE_LINTOK(p, 100, int);
- X succeed("100 ints malloc'd (or else)\n");
- X REALLOC_OR_ELSE_LINTOK(p, 200, int);
- X succeed("200 ints realloc'd (or else)\n");
- X
- X#undef ERROR_EXIT_LINTOK
- X#define ERROR_EXIT_LINTOK(nelem, size) \
- X fail("memory allocation failed\n");
- X
- X MR_ALLOC_OR_ELSE_LINTOK(p, 400, int);
- X succeed("400 ints mr_alloc'd (realloc'd) (or else)\n");
- X
- X exit(0);
- X return 0; /* shuts up HP-UX lint */
- X}
- X
- Xfail(s)
- X char *s;
- X{
- X fputs(s, stdout);
- X exit(1);
- X}
- X
- Xsucceed(s)
- X char *s;
- X{
- X fputs(s, stdout);
- X return;
- X}
- END_OF_t_memlintok.c
- if test 1438 -ne `wc -c <t_memlintok.c`; then
- echo shar: \"t_memlintok.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- echo shar: End of shell archive.
- exit 0
-
-